package com.example.testproj.http;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.example.testproj.R;
import com.example.testproj.utils.ThreadUtil;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;

import static com.example.testproj.http.HttpEntry.splitString;

public class HttpTestActivity extends AppCompatActivity {
    private static final String TAG = "HttpTestActivity";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_http_test);

        ThreadUtil.getThreadUtil().submit(new Runnable() {
            @Override
            public void run() {
                ServerSocket serverSocket = null;
                try {
                    serverSocket = new ServerSocket(8888);
                    while (true) {
                        Log.d(TAG, "run: 准备接受");
                        Socket socket = serverSocket.accept();
                        Log.d(TAG, "run: 接收成功一个");
                        ThreadUtil.getThreadUtil().submit(new SocketRunable(socket));
                    }

                } catch (IOException e) {
                    e.printStackTrace();

                } finally {
                    if (serverSocket != null) {
                        try {
                            serverSocket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
    }

    public static class SocketRunable implements Runnable {
        private Socket socket;
        private static int[] findChar = new int[]{13, 10, 13, 10};


        public SocketRunable(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                Log.d(TAG, "run: 准备处理数据");
                HttpEntry header = readHttpHeader(socket);
                HttpResponseEntry httpResponseEntry = new HttpResponseEntry.Builder().builder();

                sendMessage(socket,httpResponseEntry.getHeaderMessage()+ splitString);
                File file=new File("/sdcard/test.html");
                sendMessage(socket,new FileInputStream(file));

//                String content=readMessage(socket);
                Log.d(TAG, "run: header===" + header);
                Log.d(TAG, "run: response===" + httpResponseEntry.getHeaderMessage());
//                Log.d(TAG, "run: content===" + content);
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, "run: " + e.getMessage());
            } finally {
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        private boolean sendMessage(Socket socket,InputStream content) {
            OutputStream outputStream=null;
            try {
                outputStream=socket.getOutputStream();
                BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(outputStream);
                BufferedInputStream bufferedInputStream=new BufferedInputStream(content);
                int length=0;
                byte[] b = new byte[1024 * 5];
                while ((length=bufferedInputStream.read(b))!=-1){
                    //Log.d(TAG, "sendMessage: "+(char) b);
                    bufferedOutputStream.write(b,0,length);
                }

                bufferedOutputStream.flush();
//                OutputStreamWriter outputStreamWriter=new OutputStreamWriter(outputStream);
//                outputStreamWriter.write(content);
//                outputStream.flush();
                Log.d(TAG, "sendMessage: 发送成功"+content);
                return true;
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
//                if (outputStream!=null){
//                    try {
//                        outputStream.close();
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }
//                }
            }
            return false;
        }

        private boolean sendMessage(Socket socket,String content) {
            OutputStream outputStream=null;
            try {
                outputStream=socket.getOutputStream();
                BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(outputStream);
                bufferedOutputStream.write(content.getBytes());
                bufferedOutputStream.flush();
//                OutputStreamWriter outputStreamWriter=new OutputStreamWriter(outputStream);
//                outputStreamWriter.write(content);
//                outputStream.flush();
                Log.d(TAG, "sendMessage: 发送成功"+content);
                return true;
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
//                if (outputStream!=null){
//                    try {
//                        outputStream.close();
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }
//                }
            }
            return false;
        }

        private HttpEntry readHttpHeader(Socket socket) {
            try {
                String sb = readMessage(socket);

                HttpEntry socHttpEntry = new HttpRequestEntry();
                String[] content = sb.toString().split(splitString);
                String[] baseInfo = content[0].split(" ");
                if (baseInfo.length < 3) {
                    return null;
                }
                socHttpEntry.setMethod(baseInfo[0]);
                socHttpEntry.setPath(baseInfo[1]);
                socHttpEntry.setHttpVersion(baseInfo[2]);

                int index = 0;
                for (String bean :
                        content) {
                    if (index > 0) {
                        Map.Entry<String, String> entry = parseHeader(bean);
                        socHttpEntry.addHeader(entry.getKey(), entry.getValue());
                    }
                    index++;
                }
                return socHttpEntry;
            } catch (Exception e) {
                e.printStackTrace();
            }


            return null;
        }

        private String readMessage(Socket socket) throws IOException {
            int findIndex = 0;
            InputStream inputStream = null;
            try {
                inputStream = socket.getInputStream();
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                int b = 0;
                StringBuffer sb = new StringBuffer();
                while ((b = inputStreamReader.read()) != -1) {
                    sb.append((char) b);
                    if (findChar[findIndex] == b) {
                        findIndex++;
                        if (findIndex >= 4) {
                            break;
                        }
                    } else {
                        findIndex = 0;
                    }
                }
                return sb.toString();
            } catch (IOException e) {
                e.printStackTrace();
                Log.e(TAG, "readMessage: "+e.getMessage() );
            }finally {
//                if (inputStream!=null){
//                    try {
//                        inputStream.close();
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }
//                }
            }
            return null;
        }

        private Map.Entry<String, String> parseHeader(String content) {
            int index = content.indexOf(":");
            Entry entry = new Entry(content.substring(0, index), content.substring(index + 1));
            return entry;
        }

        static class Entry implements Map.Entry<String, String> {
            String key;
            String value;

            public Entry(String key, String value) {
                this.key = key;
                this.value = value;
            }

            @Override
            public String getKey() {
                return key;
            }

            @Override
            public String getValue() {
                return value;
            }

            @Override
            public String setValue(String object) {
                key = object;
                return null;
            }
        }
    }
}
